//  File:         Organizer.cpp
//  Author:       Scott Nordmann & Lauren Wallace
//  Description:  Non-inline member function definitions.
#include "Organizer.h"
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include "Entry.h"


using namespace std;

Organizer::Organizer()
{
	ifstream ifsave;
	
	ifsave.open("save.txt");
	if (!ifsave)// make sure that the file is open now
	{
		exit(1);
	}

	startUp(ifsave);

	currentUser = NULL;
	
	ifsave.close();
}

Organizer::~Organizer()
{
	ofstream ofsave;
	
	ofsave.open("save.txt");
	
	shutDown(ofsave);
	
	ofsave.close();
}

void Organizer::startUp(ifstream& ifsave)
{
	int numUsers, ctr;
	string name;
	string pass;
	
	ifsave >> numUsers;
	ctr=0;
	while (ctr != numUsers)
	{
		++ctr;
		ifsave >> name;
		ifsave >>pass;
		createUser(name,pass,ifsave);
	}
}


void Organizer::shutDown(ofstream& ofsave)
{
	vector<User*>::iterator iter;
	iter = users.begin();

	ofsave << users.size()<< endl;
	
	for (iter=users.begin();iter != users.end(); ++iter)
	{
		ofsave << (*iter)->getUsername()<<endl;
		ofsave << (*iter)->getPassword()<<endl;
		(*iter)->shutDown(ofsave);
		
	}
}

void Organizer::showMenu()
{
	char command = ' ';
	while (toupper(command) != 'Q')
	{
		if (!currentUser)
		{
			showLogInScreen();
		}
		else if(currentUser->getUsername() != "admin")
		{
			cout << "PORG Personal Organizer System" << endl << endl;

			cout << "N: My Notebook" << endl;
			cout << "C: My Calendar" << endl;
			cout << "L: My To Do List" << endl;
			cout << "R: My Rolodex" << endl;
			cout << "T: My Tags" << endl;
			cout << "I: My Inbox" << endl;
			cout << "O: Log Out" << endl;
			cout << "Q: Quit" << endl << endl;

			cout << "Please enter your selection: ";
		
			cin >> command;

			switch (toupper(command))
			{
			case 'N':
				system("cls");
				showNotebookMenu();
				break;
			case 'C':
				system("cls");
				showCalendarMenu();
				break;
			case 'L':
				system("cls");
				showToDoListMenu();
				break;
			case 'T':
				system("cls");
				showTagMenu();
				break;
			case 'I':
				system("cls");
				showInboxMenu();
				break;
			case 'O':
				system("cls");
				deliverMail();
				currentUser=NULL;
				cin.ignore();
				break;
			case 'Q':
				deliverMail();
				cout << "Thank you for using PORG!" << endl << endl;
				break;
			default:
				cout << "Invalid selection." << endl << endl;
				cout << "Press any key to continue . . .";

				cin.ignore();
				cin.get();

				system("cls");
				break;
			}
		}
		else
		{
			showAdminMenu();
			currentUser=NULL;
			cin.ignore();
			system("cls");
		}
	}
}

void Organizer::showLogInScreen()
{
	string username;
	string password;

	cout << "Welcome to PORG!" << endl << endl;
	cout << "Please Login" << endl << endl;

	do
	{
		cout << "Username: ";
		getline(cin, username);
		cout << "Password: ";
		getline(cin, password);
		cout << endl;
	}
	while (!logIn(username, password));

	cout << "Login successful." << endl << endl;
	cout << "Press any key to continue . . .";

	cin.get();

	system("cls");
}

void Organizer::showNotebookMenu()
{
	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "PORG: My Notebook" << endl << endl;

		cout << "C: Create Note" << endl;
		cout << "B: Browse Notes" << endl;
		cout << "M: Return to Main Menu" << endl << endl;

		cout << "Please enter your selection: ";
		cin >> command;
		cin.ignore();

		switch (toupper(command))
		{
		case 'C':
			system("cls");
			cout << "Creating Note" << endl << endl;
			currentUser->createNote();
			break;
		case 'B':
			system("cls");
			cout << "Browsing Notes" << endl << endl;
			currentUser->viewNotebook();
			break;
		case 'M':
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		if (toupper(command) != 'M')
		{
			cout << "Press any key to continue . . .";

			cin.get();
		}

		system("cls");
	}
}

void Organizer::showCalendarMenu()
{
	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "PORG: My Calendar" << endl << endl;

		cout << "C: Create Event" << endl;
		cout << "E: Edit Event" << endl;
		cout << "D: Delete Event" << endl;
		cout << "B: Browse Events" << endl;
		cout << "M: Return to Main Menu" << endl << endl;

		cout << "Please enter your selection: ";
		cin >> command;
		cin.ignore();

		switch (toupper(command))
		{
		case 'C':
			system("cls");
			currentUser->createEvent();
			break;
		case 'E':
			system("cls");
			cout << "Editing Event" << endl << endl;
			currentUser->editEvent();
			break;
		case 'D':
			system("cls");
			cout << "Deleting Event" << endl << endl;
			currentUser->deleteEvent();
			break;
		case 'B':
			system("cls");
			cout << "Browsing Calendar" << endl << endl;
			currentUser->viewCalendar();
			break;
		case 'M':
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		if (toupper(command) != 'M')
		{
			cout << "Press any key to continue . . .";

			cin.ignore();
			cin.get();
		}

		system("cls");
	}
}

void Organizer::showToDoListMenu()
{
	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "PORG: My To Do List" << endl << endl;

		cout << "C: Create Task" << endl;
		cout << "B: Browse Tasks" << endl;
		cout << "M: Return to Main Menu" << endl << endl;

		cout << "Please enter your selection: ";
		cin >> command;
		cin.ignore();

		switch (toupper(command))
		{
		case 'C':
			system("cls");
			cout << "Creating Task" << endl << endl;
			currentUser->createTask();
			break;
		case 'B':
			system("cls");
			cout << "Browsing Tasks" << endl << endl;
			currentUser->viewToDoList();
			break;
		case 'M':
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		if (toupper(command) != 'M')
		{
			cout << "Press any key to continue . . .";

			cin.ignore();
			cin.get();
		}

		system("cls");
	}
}

void Organizer::showTagMenu()
{
	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "PORG: My Tags" << endl << endl;

		cout << "C: Create Tag" << endl;
		cout << "B: Browse Tags" << endl;
		cout << "M: Return to Main Menu" << endl << endl;

		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'C':
			system("cls");
			cout << "Creating Tag" << endl << endl;
			currentUser->createTag();
			break;
		case 'B':
			system("cls");
			cout << "Browsing Tags" << endl << endl;
			currentUser->viewByTag();
			break;
		case 'M':
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		if (toupper(command) != 'M')
		{
			cout << "Press any key to continue . . .";

			cin.ignore();
			cin.get();
		}

		system("cls");
	}
}

void Organizer::showInboxMenu()
{
	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "PORG: My Inbox" << endl << endl;

		cout << "S: Send Entry" << endl;
		cout << "B: Browse Inbox" << endl;
		cout << "M: Return to Main Menu" << endl << endl;

		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'S':
			system("cls");
			cout << "Sending Entry" << endl << endl;
			currentUser->sendMail();
			break;
		case 'B':
			system("cls");
			cout << "Browsing Inbox" << endl << endl;
			currentUser->checkMail();
			break;
		case 'M':
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		if (toupper(command) != 'M')
		{
			cout << "Press any key to continue . . .";

			cin.ignore();
			cin.get();
		}

		system("cls");
	}
}
bool Organizer::logIn(const string& u, const string& pwd)
{
	bool pass=false;
	vector<User*>::iterator iter;
	for (iter=users.begin();iter!=users.end();++iter)
	{
		if (  (*iter)->getUsername() == u )
		{
			if ((*iter)->getPassword() == pwd)
			{
				currentUser=*iter;
				pass=true;
			}
		}
	}
	return pass;
}

bool Organizer::createUser(const string& user, const string& pass, ifstream& ifsave)
{
	User* temp = new User(user, pass, ifsave);
	users.push_back(temp);
	return true; //for now
}

void Organizer::showAdminMenu()
{	char command = ' ';
	while (toupper(command) != 'Q')
	{
		cout << "Administrative menu" << endl << endl;

		cout << "B: Browse Users" << endl;
		cout << "E: Edit User" << endl;
		cout << "C: Create new User" << endl;
		cout << "D: Delete User" << endl;
		cout << "Q: Quit" << endl << endl;

		cout << "Please enter your selection: ";

		cin >> command;
		cin.ignore();
		switch (toupper(command))
		{
		case 'B':
			system("cls");
			display();
			break;
		case 'E':
			system("cls");
			editUser();
			break;
		case 'C':
			system("cls");
			createUser();
			break;
		case 'D':
			system("cls");
			deleteUser( *choiceDisplay() );
			break;
		case 'Q':
			cout << "Logging out Administrator" << endl << endl;
			break;
		default:
			cout << "Invalid selection." << endl << endl;
			cout << "Press any key to continue . . .";

			cin.ignore();
			cin.get();

			system("cls");
			break;
		}
	}
}
void Organizer::display()const
{
	vector<User*>::const_iterator iter;
	int ctr=0;
	for (iter=users.begin() ; iter!=users.end() ; ++iter )
	{
		++ctr;
		cout << "[" << ctr << "]" << endl;
		(*iter)->display();
		cout << endl;
	}
	cin.ignore();
	cin.get();

	system("cls");
}
User* Organizer::choiceDisplay()
{	
	int choice;
	vector<User*>::const_iterator iter;
	int ctr=0;
	for (iter=users.begin() ; iter!=users.end() ; ++iter )
	{
		++ctr;
		cout << "[" << ctr << "]" << endl;
		(*iter)->display();
		cout << endl;
	}

	cout << "Which note would you like to edit (enter number 1 - " << ctr << ")? ";
	cin >> choice;
	cin.ignore();
	// range checked here- if it's out of bounds put choice in bounds
	if (choice < 1)
		choice = 1;
	if (choice > ctr)
		choice = ctr;
			
	--choice;//decriment choice so that it works with vector
			
	system("cls");
	return users.at(choice);
}
void Organizer::createUser()
{
	User* use;
	
	use = new User;

	use->populate();

	users.push_back(use);
	
}
void Organizer::editUser()
{

	User* current;

	current = choiceDisplay();
		
	char command = ' ';
	string input;
	
	while (toupper(command) != 'M')
	{
		system("cls");
		current->display();
		cout << "Editing a User" << endl << endl;
		
		cout << "N: Edit Name" << endl;
		cout << "P: Edit Password" << endl << endl;
		cout << "M: return to Menu" << endl << endl;
		
		cout << "Please enter your selection: ";
		cin >> command;
		cin.ignore();

		switch (toupper(command))
		{
		case 'N':
			if (current->getUsername() == "admin")
				cout << "you cannot change the admin";
			else
			{
				cout << "New Name?: ";
				getline(cin, input);
				if (input != "admin")
					current->setUsername(input);
				else
					cout << "invalid name";
			}
			break;
		
		case 'P':
			cout << "New Password?: ";
			getline(cin, input);
			current->setPassword(input);
			break;
		
		case 'M':
			break;

		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}
	}
}
bool Organizer::deleteUser(User& u)
{

	bool found = false;

	vector<User*>::iterator iter = users.begin();
	while (!found && iter != users.end())
	{
		if ((**iter) == u)
		{
		found = true;
		}
		else
		{
		++iter;
		}
	}
	if (found ==true)
	{
		delete (*iter);
		users.erase(iter);
	}
	return found;
}



void Organizer::deliverMail()
{
	string sendTo;
	bool sent=false;
	vector<Entry*> sentMail;
	sentMail = *currentUser->getSentMail();
	
	vector<Entry*>::iterator mailIter;
	vector<User*>::iterator userIter;

	mailIter =  sentMail.begin();

	while ( mailIter != sentMail.end())
	{	
		
		sendTo = (*mailIter)->getSendTo();
		for (userIter=users.begin() ;userIter!=users.end() ; ++userIter )
		{
			if ( (*userIter)->getUsername() == (*mailIter)->getSendTo())
			{
				//send sent mail
				((*userIter)->getInbox())->push_back(*mailIter);
				sent=true;
			}
		}
		if (sent != true)
		{
			( currentUser->getInbox())->push_back(*mailIter);//undelivered mail is sent back to sender
		}
		sent=true;
		++mailIter;
	}
	(currentUser->getSentMail())->clear();
	
}